/*************************************************************/
/*  WRITTEN BY BSPAL using turbo C 2.01                      */
/*************************************************************/
#include <dos.h>
#include <stdio.h>
#define VGA256 0x13
#define TEXT 0x03
#define PALETTE_MASK 0x3c6
#define PALETTE_REGISTER_RD 0x3c7
#define PALETTE_REGISTER_WR 0x3c8
#define PALETTE_DATA 0x3c9
#define BYTE unsigned char
#define WORD unsigned short int
#define DWORD unsigned long int
#define clsgraph() initgraph(0x03)
BYTE far * video_buf = (char far *)0xA0000000L;
enum bool {false,true};
#define bool int
/*-------------------------------------------------*/
typedef struct RGB_BMP_typ
{
	BYTE red;
	BYTE green;
	BYTE blue;
}RGB_BMP,*RGB_BMP_ptr;
/*-------------------------------------------------*/
typedef struct
{
	DWORD reserved;
	WORD width;
	WORD length;

}RGMH;
/*-------------------------------------------------*/
void Set_BMP_Palette_Register(int index,RGB_BMP_ptr color)
{
	outp(PALETTE_MASK,0xff);
	outp(PALETTE_REGISTER_WR,index);
	outp(PALETTE_DATA,color->red);
	outp(PALETTE_DATA,color->green);
	outp(PALETTE_DATA,color->blue);
}
/*-------------------------------------------------*/
void initgraph(int mode)
{
	DWORD i;
	union REGS in,out;
	in.h.ah=0;
	in.h.al=(unsigned char)mode;
	int86(0x10,&in,&out);
	for(i=0;i<(320*100);i++)
	 video_buf[i] = 30;
	for(i=0;i<320*100;i++)
	 video_buf[i+320*100] = 30;
}
/*------------------------------------------------*/
setpal(const char *filename)
{
	FILE *fp = fopen(filename,"rb");
	DWORD filelen = 0; int i = 0;
	RGB_BMP rb[256];
	if(fp)
	{
		fseek(fp,0,SEEK_END);
		filelen = ftell(fp);
		if(filelen !=768 && filelen != 1536) return 0;
		fseek(fp,0,SEEK_SET);
		fread(&rb,768,1,fp);
		for(i=0;i<256;i++)
			Set_BMP_Palette_Register(i,&(rb[i]));
		fclose(fp);
		return 1;
	}
	return 0;
}
/**************************************************/
#define PAL_NOCLIP 0
#define PAL_CLIP 1
void putpate(BYTE * source,const int x,const int y,const DWORD scrw,const DWORD scrh,BYTE far* desbuf,int cut);
/* Parameters
	source  : the source buffer where the picture stored
	x,y     : the coordinates predicates where the pate to put
	disp    : displacement of desbuf(stands for the screen width)
	desbuf  : where the pate put
*/
/**************************************************/
void main()
{
	int result;FILE *fp;
	DWORD filelen;
	BYTE *buffer,*buffer1,*buffer2,*buffer3;
	clrscr();
	initgraph(0x13);
	fp = fopen("81.rgm","rb");
	setpal("01.pat");
	if(fp)
	{
      fseek(fp,0,SEEK_END);
		filelen = ftell(fp);
		buffer = (BYTE*)malloc(filelen);
		fseek(fp,0,SEEK_SET);
		fread(buffer,filelen,1,fp);
		fclose(fp);
	}
	fp = fopen("20.rgm","rb");
   if(fp)
	{
      fseek(fp,0,SEEK_END);
		filelen = ftell(fp);
		buffer1 = (BYTE*)malloc(filelen);
		fseek(fp,0,SEEK_SET);
		fread(buffer1,filelen,1,fp);
		fclose(fp);
	}
	fp = fopen("12.rgm","rb");
   if(fp)
	{
      fseek(fp,0,SEEK_END);
		filelen = ftell(fp);
		buffer2 = (BYTE*)malloc(filelen);
		fseek(fp,0,SEEK_SET);
		fread(buffer2,filelen,1,fp);
		fclose(fp);
	}
	fp = fopen("56.rgm","rb");
   if(fp)
	{
      fseek(fp,0,SEEK_END);
		filelen = ftell(fp);
		buffer3 = (BYTE*)malloc(filelen);
		fseek(fp,0,SEEK_SET);
		fread(buffer3,filelen,1,fp);
		fclose(fp);
	}
	putpate(buffer,-60,120,320,200,video_buf,PAL_CLIP);
	putpate(buffer1,240,85,320,200,video_buf,PAL_CLIP);
	putpate(buffer2,5,5,320,200,video_buf,PAL_CLIP);
	putpate(buffer3,100,160,320,200,video_buf,PAL_NOCLIP);
	getch();
	free(buffer),free(buffer1),free(buffer2),free(buffer3);
	clsgraph();
}

/**************************************************/
void putpate(BYTE* buffer,const int x,const int y,const DWORD scrw,const DWORD scrh,BYTE far* desbuf,int cut)
{
	RGMH head;
	register BYTE num;
	DWORD dp = 8,i = 0,j = 0,k;
	WORD flag;
	memcpy(&head,buffer,sizeof(head));
	while(j<head.length)
	{
		flag = head.width; i = 0;
		while(flag)
		{
			num = buffer[dp];
			if(num>=0x80)          /* it is transparent pixel */
			{
				num -= 0x80;
				flag -= num;
				i += num;
				dp++;
				if(num == 0x7F) continue;  /* very special case! */
			}
			if(flag == 0) break;   /* one line finished */
			num = buffer[dp];      /* get the nontrans number */
			dp++;                  /* move to nontrans pixels */
			for(k=0;k<num;k++,i++)
			{
				switch(cut) /* does the picture need clip ? */
				{
					case 1:  if((signed)(x+i)<0||(x+i)>=scrw)continue;
								if((signed)(y+j)<0)continue;
								break;
					defalut: break;
				}
            if(cut&&(signed)y>0)if((y+j)>scrh) return;
				desbuf[scrw*(y+j)+x+i] = buffer[dp+k];
			}
			dp+=num;               /* num nontrans pixel done */
			flag-=num;             /* num pixel pass */
		}
		j++;
	}
}
